package com.yang.core.api;

import lombok.extern.slf4j.Slf4j;

import com.yang.core.client.HttpClient;
import com.yang.core.client.RequestExecutor;
import com.yang.core.client.ResponseProcessor;
import com.yang.core.config.RestClientConfig;
import com.yang.core.model.*;
import com.yang.core.api.RestClientBuilder;
import com.yang.core.api.RestClientException;

import java.time.Duration;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 核心RestClient类
 * 支持开箱即用的功能和高度可扩展性
 */
@Slf4j
public class RestClient implements AutoCloseable {

    private final RestClientConfig config;
    private final HttpClient httpClient;
    private final RequestExecutor requestExecutor;
    private final ResponseProcessor responseProcessor;

    RestClient(RestClientConfig config) {
        this.config = config;
        this.httpClient = createHttpClient(config);
        this.requestExecutor = new RequestExecutor(httpClient, config);
        this.responseProcessor = new ResponseProcessor(config);
    }

    /**
     * 创建RestClient实例
     */
    public static RestClient create() {
        return builder().build();
    }

    /**
     * 创建RestClient构建器
     */
    public static RestClientBuilder builder() {
        return new RestClientBuilder();
    }

    /**
     * 便捷方法 - 开发环境
     */
    public static RestClient forDevelopment() {
        return builder().forDevelopment().build();
    }

    /**
     * 便捷方法 - 生产环境
     */
    public static RestClient forProduction() {
        return builder().forProduction().build();
    }

    /**
     * 便捷方法 - 高性能模式
     */
    public static RestClient forHighPerformance() {
        return builder().forHighPerformance().build();
    }

    /**
     * GET请求
     */
    public HttpResponse<String> get(String url) {
        return get(url, String.class);
    }

    public <T> HttpResponse<T> get(String url, Class<T> responseType) {
        return execute(HttpMethod.GET, url, null, responseType);
    }

    public <T> HttpResponse<T> get(String url, java.lang.reflect.Type responseType) {
        return execute(HttpMethod.GET, url, null, responseType);
    }

    /**
     * POST请求
     */
    public HttpResponse<String> post(String url, Object body) {
        return post(url, body, String.class);
    }

    public <T> HttpResponse<T> post(String url, Object body, Class<T> responseType) {
        return execute(HttpMethod.POST, url, body, responseType);
    }

    public <T> HttpResponse<T> post(String url, Object body, java.lang.reflect.Type responseType) {
        return execute(HttpMethod.POST, url, body, responseType);
    }

    /**
     * PUT请求
     */
    public HttpResponse<String> put(String url, Object body) {
        return put(url, body, String.class);
    }

    public <T> HttpResponse<T> put(String url, Object body, Class<T> responseType) {
        return execute(HttpMethod.PUT, url, body, responseType);
    }

    public <T> HttpResponse<T> put(String url, Object body, java.lang.reflect.Type responseType) {
        return execute(HttpMethod.PUT, url, body, responseType);
    }

    /**
     * DELETE请求
     */
    public HttpResponse<String> delete(String url) {
        return delete(url, String.class);
    }

    public <T> HttpResponse<T> delete(String url, Class<T> responseType) {
        return execute(HttpMethod.DELETE, url, null, responseType);
    }

    public <T> HttpResponse<T> delete(String url, java.lang.reflect.Type responseType) {
        return execute(HttpMethod.DELETE, url, null, responseType);
    }

    /**
     * 执行HTTP请求
     */
    private <T> HttpResponse<T> execute(HttpMethod method, String url, Object body, Class<T> responseType) {
        long startTime = System.currentTimeMillis();

        try {
            // 创建请求上下文
            RequestContext requestContext = RequestContext.builder()
                    .method(method.name())
                    .url(buildUrl(url))
                    .body(body)
                    .headers(config.getDefaultHeaders())
                    .build();

            // 执行前置拦截器
            config.getInterceptors().forEach(interceptor -> {
                try {
                    interceptor.preRequest(requestContext);
                } catch (Exception e) {
                    log.warn("前置拦截器执行失败", e);
                }
            });

            // 执行请求
            RawResponse rawResponse = requestExecutor.execute(requestContext);

            // 创建响应上下文
            ResponseContext responseContext = ResponseContext.builder()
                    .statusCode(rawResponse.getStatusCode())
                    .body(rawResponse.getBody())
                    .headers(rawResponse.getHeaders())
                    .responseTime(System.currentTimeMillis() - startTime)
                    .build();

            // 执行后置拦截器
            config.getInterceptors().forEach(interceptor -> {
                try {
                    interceptor.postResponse(responseContext);
                } catch (Exception e) {
                    log.warn("后置拦截器执行失败", e);
                }
            });

            // 处理响应
            return responseProcessor.process(responseContext, responseType);

        } catch (Exception e) {
            // 异常处理
            ExceptionContext exceptionContext = ExceptionContext.builder()
                    .exception(e)
                    .url(buildUrl(url))
                    .method(method.name())
                    .build();

            config.getInterceptors().forEach(interceptor -> {
                try {
                    interceptor.onError(exceptionContext);
                } catch (Exception ex) {
                    log.warn("异常拦截器执行失败", ex);
                }
            });

            if (e instanceof RestClientException) {
                throw (RestClientException) e;
            } else {
                throw new RestClientException("请求执行失败", e);
            }
        }
    }

    /**
     * 执行HTTP请求（泛型版本）
     */
    private <T> HttpResponse<T> execute(HttpMethod method, String url, Object body, java.lang.reflect.Type responseType) {
        // 类似实现，但支持泛型类型
        return null; // 简化实现
    }

    /**
     * 异步请求
     */
    public CompletableFuture<HttpResponse<String>> getAsync(String url) {
        return getAsync(url, String.class);
    }

    public <T> CompletableFuture<HttpResponse<T>> getAsync(String url, Class<T> responseType) {
        return CompletableFuture.supplyAsync(() -> get(url, responseType));
    }

    public <T> CompletableFuture<HttpResponse<T>> postAsync(String url, Object body, Class<T> responseType) {
        return CompletableFuture.supplyAsync(() -> post(url, body, responseType));
    }

    /**
     * 构建完整URL
     */
    private String buildUrl(String url) {
        if (url == null) {
            return config.getBaseUrl();
        }

        if (url.startsWith("http://") || url.startsWith("https://")) {
            return url;
        }

        String baseUrl = config.getBaseUrl();
        if (baseUrl == null || baseUrl.isEmpty()) {
            return url;
        }

        return baseUrl.endsWith("/") ? baseUrl + url.substring(1) : baseUrl + "/" + url;
    }

    /**
     * 创建HTTP客户端
     */
    private HttpClient createHttpClient(RestClientConfig config) {
        return HttpClient.builder()
                .connectTimeout(config.getConnectTimeout())
                .socketTimeout(config.getSocketTimeout())
                .maxConnectionsTotal(config.getMaxConnectionsTotal())
                .maxConnectionsPerRoute(config.getMaxConnectionsPerRoute())
                .proxyHost(config.getProxyHost())
                .proxyPort(config.getProxyPort())
                .proxyUsername(config.getProxyUsername())
                .proxyPassword(config.getProxyPassword())
                .trustAllCertificates(config.isTrustAllCertificates())
                .hostnameVerification(config.isHostnameVerification())
                .enableCompression(config.isCompressionEnabled())
                .build();
    }

    /**
     * 获取配置
     */
    public RestClientConfig getConfig() {
        return config;
    }

    /**
     * 关闭客户端
     */
    public void close() {
        if (httpClient != null) {
            httpClient.close();
            log.info("RestClient已关闭");
        }
    }

    /**
     * 获取客户端统计信息
     */
    public Map<String, Object> getStatistics() {
        return httpClient.getStatistics();
    }

    /**
     * 健康检查
     */
    public boolean isHealthy() {
        return httpClient != null && httpClient.isHealthy();
    }

    @Override
    public String toString() {
        return "RestClient{" +
                "baseUrl='" + config.getBaseUrl() + '\'' +
                ", userAgent='" + config.getUserAgent() + '\'' +
                ", maxConnections=" + config.getMaxConnectionsTotal() +
                '}';
    }
}